home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / src / haeberli / libgutil / psimg.c < prev    next >
C/C++ Source or Header  |  1994-08-01  |  13KB  |  534 lines

  1. /*
  2.  * Copyright 1991, 1992, 1993, 1994, Silicon Graphics, Inc.
  3.  * All Rights Reserved.
  4.  *
  5.  * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
  6.  * the contents of this file may not be disclosed to third parties, copied or
  7.  * duplicated in any form, in whole or in part, without the prior written
  8.  * permission of Silicon Graphics, Inc.
  9.  *
  10.  * RESTRICTED RIGHTS LEGEND:
  11.  * Use, duplication or disclosure by the Government is subject to restrictions
  12.  * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
  13.  * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
  14.  * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
  15.  * rights reserved under the Copyright Laws of the United States.
  16.  */
  17. /*
  18.  *    psimg - 
  19.  *        Convert image data into b/w or color PostScript.
  20.  *
  21.  *            Paul Haeberli - 1989
  22.  *
  23.  */
  24. #include "image.h"
  25. #include "math.h"
  26.  
  27. typedef struct printspec {
  28.     float screendensity;
  29.     float screenangle; 
  30.     float xpixperinch; 
  31.     float ypixperinch; 
  32.     float scaletrim; 
  33.     float maxxsize, maxysize;
  34.     int bitsper, linescreen;
  35. } printspec;
  36.  
  37. static short cortab[256];
  38. static int pos;
  39. static int psfirsted;
  40. static IMAGE *inimage;
  41. static int binaryout = 0;
  42.  
  43. static bwgetimgrow();
  44. static rgbgetimgrow();
  45. static hypcurve();
  46. static putpsascrow();
  47. static putpsbinrow();
  48. static makepstables();
  49. static psputchar();
  50. static intervleave3();
  51. static intervleave4();
  52.  
  53. usebinaryps(b)
  54. int b;
  55. {
  56.     binaryout = b;
  57. }
  58.  
  59. static bwgetimgrow(buf,y)
  60. short *buf;
  61. int y;
  62. {
  63.     getbwrow(inimage,buf,inimage->ysize-1-y);
  64. }
  65.  
  66. static rgbgetimgrow(buf,y,z)
  67. short *buf;
  68. int y, z;
  69. {
  70.     getrow(inimage,buf,inimage->ysize-1-y,z%inimage->zsize);
  71. }
  72.  
  73. frametobwps(outf,image) 
  74. FILE *outf;
  75. IMAGE *image;
  76. {
  77.     printspec ps;
  78.  
  79.     hypcurve(0.7);
  80.     ps.screendensity = 60.0;
  81.     ps.screenangle = 45.0;
  82.     ps.xpixperinch = -1.0;
  83.     ps.ypixperinch = -1.0;
  84.     ps.scaletrim = 1.0;
  85.     ps.bitsper = 8;
  86.     ps.linescreen = 0;
  87.     fprintf(outf,"\n translate scale\n");
  88.     fprintf(outf,"pop pop\n");
  89.     if(ps.linescreen) 
  90.     fprintf(outf,"%f %f {pop} setscreen\n",ps.screendensity,ps.screenangle);
  91.     else
  92.         fprintf(outf,"%f %f {dup mul exch dup mul add 1 exch sub} setscreen\n",
  93.                            ps.screendensity,ps.screenangle);
  94.     inimage = image;
  95.     tobwps(outf,bwgetimgrow,cortab,ps.bitsper,inimage->xsize,inimage->ysize);
  96. }
  97.  
  98. frametorgbps(outf,image) 
  99. FILE *outf;
  100. IMAGE *image;
  101. {
  102.     printspec ps;
  103.  
  104.     hypcurve(0.7);
  105.     ps.screendensity = 60.0;
  106.     ps.screenangle = 45.0;
  107.     ps.xpixperinch = -1.0;
  108.     ps.ypixperinch = -1.0;
  109.     ps.scaletrim = 1.0;
  110.     ps.bitsper = 8;
  111.     ps.linescreen = 0;
  112.     fprintf(outf,"\n translate scale\n");
  113.     fprintf(outf,"pop pop\n");
  114.     if(ps.linescreen) 
  115.         fprintf(outf,"%f %f {pop} setscreen\n",ps.screendensity,ps.screenangle);
  116.     else
  117.         fprintf(outf,"%f %f {dup mul exch dup mul add 1 exch sub} setscreen\n",
  118.                            ps.screendensity,ps.screenangle);
  119.     inimage = image;
  120.     torgbps(outf,rgbgetimgrow,cortab,ps.bitsper,inimage->xsize,inimage->ysize,1);
  121. }
  122.  
  123. static hypcurve(p)
  124. float p;
  125. {
  126.     float b;
  127.     float x, y;
  128.     int i;
  129.  
  130.     b = (1.0/p) - p;
  131.     for(i=0; i<256; i++) {
  132.     x = i/255.0;
  133.     y = 1.0-(1.0/((x*b)+p) - p)/b;
  134.     cortab[i] = (255*y)+0.5;
  135.     }
  136. }
  137.  
  138. /*
  139.  *    convert an image into B/W postscript
  140.  *
  141.  *
  142.  */
  143. static unsigned char *hi, *low;
  144.  
  145. tobwps(outf,getfunc,cortab,bitsper,xsize,ysize)
  146. FILE *outf;
  147. int (*getfunc)();
  148. short cortab[256];
  149. int bitsper, xsize, ysize;
  150. {
  151.     int y, picstrlen;
  152.     unsigned short *buf;
  153.  
  154.     picstrlen = xsize*bitsper;
  155.     picstrlen = (picstrlen+7)/8;
  156.  
  157. /* allocate the pixel buffer */
  158.     fprintf(outf,"/picstr %d string def\n",picstrlen);
  159.  
  160.     fprintf(outf,"%d %d %d\n",xsize,ysize,bitsper);
  161.     fprintf(outf,"[%d 0 0 -%d 0 %d]\n",xsize,ysize,ysize); 
  162.     if(binaryout) {
  163.     fprintf(outf,"{currentfile picstr readstring pop}\n");
  164.         fprintf(outf,"image\r");
  165.     } else  {
  166.     fprintf(outf,"{currentfile picstr readhexstring pop}\n");
  167.         fprintf(outf,"image\n");
  168.     }
  169.  
  170. /* send out the picture */
  171.     buf = (unsigned short *)malloc(xsize*sizeof(short));
  172.     pos = 0;
  173.     for( y=0; y<ysize; y++ ) {
  174.     (getfunc)(buf,y);
  175.     applytable(buf,cortab,xsize);
  176.     putpsrow(outf,buf,picstrlen,bitsper);
  177.     }
  178.     free(buf);
  179.     fprintf(outf,"\n");
  180. }
  181.  
  182. /*
  183.  *    convert an image into rgb postscript
  184.  *
  185.  *
  186.  */
  187. torgbps(outf,getfunc,cortab,bitsper,xsize,ysize,nproc)
  188. FILE *outf;
  189. int (*getfunc)();
  190. short cortab[256];
  191. int bitsper, xsize, ysize, nproc;
  192. {
  193.     int y, z, picstrlen;
  194.     unsigned short *rbuf, *gbuf, *bbuf, *rgbbuf;
  195.  
  196.     picstrlen = xsize*bitsper;
  197.     picstrlen = (picstrlen+7)/8;
  198.  
  199.     rbuf = (unsigned short *)malloc(xsize*sizeof(short));
  200.     gbuf = (unsigned short *)malloc(xsize*sizeof(short));
  201.     bbuf = (unsigned short *)malloc(xsize*sizeof(short));
  202.     rgbbuf = (unsigned short *)malloc(3*xsize*sizeof(short));
  203.     if(nproc == 1) {
  204. /* allocate the pixel buffer */
  205.     fprintf(outf,"/istr %d string def\n",3*picstrlen);
  206.     fprintf(outf,"%d %d %d\n",xsize,ysize,bitsper);
  207.     fprintf(outf,"[%d 0 0 -%d 0 %d]\n",xsize,ysize,ysize); 
  208.     if(binaryout) {
  209.         fprintf(outf,"{currentfile istr readstring pop}\n");
  210.         fprintf(outf,"false 3\n");
  211.         fprintf(outf,"colorimage\r");
  212.     } else  {
  213.         fprintf(outf,"{currentfile istr readhexstring pop}\n");
  214.         fprintf(outf,"false 3\n");
  215.         fprintf(outf,"colorimage\n");
  216.     }
  217.  
  218. /* send out the picture */
  219.     pos = 0;
  220.     for( y=0; y<ysize; y++ ) {
  221.         (getfunc)(rbuf,y,0);
  222.         applytable(rbuf,cortab,xsize);
  223.         (getfunc)(gbuf,y,1);
  224.         applytable(gbuf,cortab,xsize);
  225.         (getfunc)(bbuf,y,2);
  226.         applytable(bbuf,cortab,xsize);
  227.         intervleave3(rbuf,gbuf,bbuf,rgbbuf,xsize);
  228.         putpsrow(outf,rgbbuf,3*picstrlen,bitsper);
  229.     }
  230.     } else {
  231. /* allocate the pixel buffer */
  232.     fprintf(outf,"/rstr %d string def\n",picstrlen);
  233.     fprintf(outf,"/gstr %d string def\n",picstrlen);
  234.     fprintf(outf,"/bstr %d string def\n",picstrlen);
  235.  
  236.     fprintf(outf,"%d %d %d\n",xsize,ysize,bitsper);
  237.     fprintf(outf,"[%d 0 0 -%d 0 %d]\n",xsize,ysize,ysize); 
  238.     if(binaryout) {
  239.         fprintf(outf,"{currentfile rstr readstring pop}\n");
  240.         fprintf(outf,"{currentfile gstr readstring pop}\n");
  241.         fprintf(outf,"{currentfile bstr readstring pop}\n");
  242.         fprintf(outf,"true 3\n");
  243.         fprintf(outf,"colorimage\r");
  244.     } else  {
  245.         fprintf(outf,"{currentfile rstr readhexstring pop}\n");
  246.         fprintf(outf,"{currentfile gstr readhexstring pop}\n");
  247.         fprintf(outf,"{currentfile bstr readhexstring pop}\n");
  248.         fprintf(outf,"true 3\n");
  249.         fprintf(outf,"colorimage\n");
  250.     }
  251.  
  252. /* send out the picture */
  253.     pos = 0;
  254.     for( y=0; y<ysize; y++ ) {
  255.         (getfunc)(rbuf,y,0);
  256.         applytable(rbuf,cortab,xsize);
  257.         (getfunc)(gbuf,y,1);
  258.         applytable(gbuf,cortab,xsize);
  259.         (getfunc)(bbuf,y,2);
  260.         applytable(bbuf,cortab,xsize);
  261.         putpsrow(outf,rbuf,picstrlen,bitsper);
  262.         putpsrow(outf,gbuf,picstrlen,bitsper);
  263.         putpsrow(outf,bbuf,picstrlen,bitsper);
  264.     }
  265.     }
  266.     free(rbuf);
  267.     free(gbuf);
  268.     free(bbuf);
  269.     free(rgbbuf);
  270.     fprintf(outf,"\n");
  271. }
  272.  
  273. /*
  274.  *    convert an image into cmyk postscript
  275.  *
  276.  *
  277.  */
  278. tocmykps(outf,getfunc,cortab,bitsper,xsize,ysize,nproc)
  279. FILE *outf;
  280. int (*getfunc)();
  281. short cortab[256];
  282. int bitsper, xsize, ysize, nproc;
  283. {
  284.     int y, z, picstrlen;
  285.     unsigned short *rbuf, *gbuf, *bbuf;
  286.     unsigned short *cbuf, *mbuf, *ybuf, *kbuf;
  287.     unsigned short *cmykbuf;
  288.  
  289.     picstrlen = xsize*bitsper;
  290.     picstrlen = (picstrlen+7)/8;
  291.  
  292.     rbuf = (unsigned short *)malloc(xsize*sizeof(short));
  293.     gbuf = (unsigned short *)malloc(xsize*sizeof(short));
  294.     bbuf = (unsigned short *)malloc(xsize*sizeof(short));
  295.     cbuf = (unsigned short *)malloc(xsize*sizeof(short));
  296.     mbuf = (unsigned short *)malloc(xsize*sizeof(short));
  297.     ybuf = (unsigned short *)malloc(xsize*sizeof(short));
  298.     kbuf = (unsigned short *)malloc(xsize*sizeof(short));
  299.     cmykbuf = (unsigned short *)malloc(4*xsize*sizeof(short));
  300.     if(nproc == 1) {
  301. /* allocate the pixel buffer */
  302.     fprintf(outf,"/istr %d string def\n",4*picstrlen);
  303.     fprintf(outf,"%d %d %d\n",xsize,ysize,bitsper);
  304.     fprintf(outf,"[%d 0 0 -%d 0 %d]\n",xsize,ysize,ysize); 
  305.     if(binaryout) {
  306.         fprintf(outf,"{currentfile istr readstring pop}\n");
  307.         fprintf(outf,"false 4\n");
  308.         fprintf(outf,"colorimage\r");
  309.     } else  {
  310.         fprintf(outf,"{currentfile istr readhexstring pop}\n");
  311.         fprintf(outf,"false 4\n");
  312.         fprintf(outf,"colorimage\n");
  313.     }
  314.  
  315. /* send out the picture */
  316.     pos = 0;
  317.     for( y=0; y<ysize; y++ ) {
  318.         (getfunc)(rbuf,y,0);
  319.         (getfunc)(gbuf,y,1);
  320.         (getfunc)(bbuf,y,2);
  321.         vrgb_to_cmyk(rbuf,gbuf,bbuf,cbuf,mbuf,ybuf,kbuf,cortab,xsize);
  322.         intervleave4(cbuf,mbuf,ybuf,kbuf,cmykbuf,xsize);
  323.         putpsrow(outf,cmykbuf,4*picstrlen,bitsper);
  324.     }
  325.     } else {
  326. /* allocate the pixel buffer */
  327.     fprintf(outf,"/cstr %d string def\n",picstrlen);
  328.     fprintf(outf,"/mstr %d string def\n",picstrlen);
  329.     fprintf(outf,"/ystr %d string def\n",picstrlen);
  330.     fprintf(outf,"/kstr %d string def\n",picstrlen);
  331.  
  332.     fprintf(outf,"%d %d %d\n",xsize,ysize,bitsper);
  333.     fprintf(outf,"[%d 0 0 -%d 0 %d]\n",xsize,ysize,ysize); 
  334.  
  335.     if(binaryout) {
  336.         fprintf(outf,"{currentfile cstr readstring pop}\n");
  337.         fprintf(outf,"{currentfile mstr readstring pop}\n");
  338.         fprintf(outf,"{currentfile ystr readstring pop}\n");
  339.         fprintf(outf,"{currentfile kstr readstring pop}\n");
  340.         fprintf(outf,"true 4\n");
  341.         fprintf(outf,"colorimage\r");
  342.     } else  {
  343.         fprintf(outf,"{currentfile cstr readhexstring pop}\n");
  344.         fprintf(outf,"{currentfile mstr readhexstring pop}\n");
  345.         fprintf(outf,"{currentfile ystr readhexstring pop}\n");
  346.         fprintf(outf,"{currentfile kstr readhexstring pop}\n");
  347.         fprintf(outf,"true 4\n");
  348.         fprintf(outf,"colorimage\n");
  349.     }
  350.  
  351. /* send out the picture */
  352.     pos = 0;
  353.     for( y=0; y<ysize; y++ ) {
  354.         (getfunc)(rbuf,y,0);
  355.         (getfunc)(gbuf,y,1);
  356.         (getfunc)(bbuf,y,2);
  357.         vrgb_to_cmyk(rbuf,gbuf,bbuf,cbuf,mbuf,ybuf,kbuf,cortab,xsize);
  358.         putpsrow(outf,cbuf,picstrlen,bitsper);
  359.         putpsrow(outf,mbuf,picstrlen,bitsper);
  360.         putpsrow(outf,ybuf,picstrlen,bitsper);
  361.         putpsrow(outf,kbuf,picstrlen,bitsper);
  362.     }
  363.     }
  364.     free(rbuf);
  365.     free(gbuf);
  366.     free(bbuf);
  367.     free(cbuf);
  368.     free(mbuf);
  369.     free(ybuf);
  370.     free(kbuf);
  371.     free(cmykbuf);
  372.     fprintf(outf,"\n");
  373. }
  374.  
  375. putpsrow(outf,buf,picstrlen,bitsper)
  376. FILE *outf;
  377. short *buf;
  378. int picstrlen, bitsper;
  379. {
  380.     if(!psfirsted) {
  381.     makepstables();
  382.     psfirsted++;
  383.     }
  384.     if(binaryout)
  385.     putpsbinrow(outf,buf,picstrlen,bitsper);
  386.     else
  387.     putpsascrow(outf,buf,picstrlen,bitsper);
  388. }
  389.  
  390. static putpsascrow(outf,buf,picstrlen,bitsper)
  391. FILE *outf;
  392. short *buf;
  393. int picstrlen, bitsper;
  394. {
  395.     int x, n, i, val;
  396.  
  397.     switch(bitsper) {
  398.     case 1:
  399.         x=0;
  400.         for(n=2*picstrlen; n--; ) {
  401.         val = 0;
  402.         for(i=0; i<4; i++) {
  403.             val <<= 1;
  404.             val |= (buf[x]&0x80) >> 7;
  405.             x++;
  406.         }
  407.         psputchar("0123456789abcdef"[val],outf);
  408.         }
  409.         break;    
  410.     case 2:
  411.         x=0;
  412.         for(n=2*picstrlen; n--; ) {
  413.         val = 0;
  414.         for(i=0; i<2; i++) {
  415.             val <<= 2;
  416.             val |= (buf[x]&0xc0) >> 6;
  417.             x++;
  418.         }
  419.         psputchar("0123456789abcdef"[val],outf);
  420.         }
  421.         break;    
  422.     case 4:
  423.         x=0;
  424.         for(n=2*picstrlen; n--; ) {
  425.         val = (buf[x]&0xf0) >> 4;
  426.         x++;
  427.         psputchar("0123456789abcdef"[val],outf);
  428.         }
  429.         break;    
  430.     case 8:
  431.         x=0;
  432.         for(n=2*picstrlen; n--; ) {
  433.         val = buf[x];
  434.         if(val > 255)
  435.             fprintf(stderr,"psimg: bad poop\n");
  436.         x++;
  437.         n--;
  438.         psputchar(hi[val],outf);
  439.         psputchar(low[val],outf);
  440.         }
  441.         break;
  442.     default:
  443.         fprintf(stderr,"psimg: bits per pixel must be a power of 2!!\n");
  444.         exit(1);
  445.     }
  446. }
  447.  
  448. static putpsbinrow(outf,buf,picstrlen,bitsper)
  449. FILE *outf;
  450. short *buf;
  451. int picstrlen, bitsper;
  452. {
  453.     int x, n, i, val;
  454.  
  455.     switch(bitsper) {
  456.     case 1:
  457.         x=0;
  458.         for(n=picstrlen; n--; ) {
  459.         val = 0;
  460.         for(i=0; i<8; i++) {
  461.             val <<= 1;
  462.             val |= (buf[x]&0x80) >> 7;
  463.             x++;
  464.         }
  465.         fputc(val,outf);
  466.         }
  467.         break;    
  468.     case 8:
  469.         x=0;
  470.         for(n=picstrlen; n--;) {
  471.         val = buf[x];
  472.         if(val > 255)
  473.             fprintf(stderr,"psimg: bad poop\n");
  474.         x++;
  475.         fputc(val,outf);
  476.         }
  477.         break;
  478.     default:
  479.         fprintf(stderr,"psimg: BLAT bits per pixel must be 1 or 8\n");
  480.         exit(1);
  481.     }
  482. }
  483.  
  484. static makepstables()
  485. {
  486.     int i;
  487.  
  488.     hi = (unsigned char *)malloc(256);
  489.     low = (unsigned char *)malloc(256);
  490.     for(i=0; i<256; i++) {
  491.     hi[i] = "0123456789abcdef"[i>>4];
  492.     low[i] = "0123456789abcdef"[i&0xf];
  493.     }
  494. }
  495.  
  496. static psputchar(c,outf)
  497. int c;
  498. FILE *(outf);
  499. {
  500.     fputc(c,outf);
  501.     if(++pos == 70) { 
  502.     fputc('\n',outf);
  503.     pos = 0;
  504.     }
  505. }
  506.  
  507. psputinit()
  508. {
  509.     pos = 0;
  510. }
  511.  
  512. static intervleave3(rbuf,gbuf,bbuf,rgbbuf,n)
  513. short *rbuf, *gbuf, *bbuf, *rgbbuf;
  514. int n;
  515. {
  516.     while(n--) {
  517.     *rgbbuf++ = *rbuf++;
  518.     *rgbbuf++ = *gbuf++;
  519.     *rgbbuf++ = *bbuf++;
  520.     }
  521. }
  522.  
  523. static intervleave4(cbuf,mbuf,ybuf,kbuf,cmykbuf,n)
  524. short *cbuf, *mbuf, *ybuf, *kbuf, *cmykbuf;
  525. int n;
  526. {
  527.     while(n--) {
  528.     *cmykbuf++ = *cbuf++;
  529.     *cmykbuf++ = *mbuf++;
  530.     *cmykbuf++ = *ybuf++;
  531.     *cmykbuf++ = *kbuf++;
  532.     }
  533. }
  534.